package com.zenglx.assembly.increasingSequence.impl;

import com.zenglx.assembly.increasingSequence.api.SequenceGeneratorApi;
import com.zenglx.assembly.increasingSequence.api.SequenceGeneratorConstant;
import com.zenglx.assembly.increasingSequence.impl.dao.SequenceGeneratorDao;
import com.zenglx.assembly.increasingSequence.impl.entity.SequenceGeneratorEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;


/**
 * 乐观锁 序列生成器
 * @author zengliangxi
 */
@ConditionalOnProperty(name = SequenceGeneratorConstant.SEQUENCE_GENERATOR_TYPE
        ,  havingValue = SequenceGeneratorConstant.SEQUENCE_GENERATOR_TYPE_LOCK)
@Component
@Slf4j
public class OptimisticLockSequenceGenerator implements SequenceGeneratorApi {

    @Value("${com.zenglx.assembly.sequenceGenerator.tableName:optimistic_lock_sequence}")
    private String tableName;

    @Autowired
    private SequenceGeneratorDao sequenceGeneratorDao;
    /**
     * 下一个Id
     *
     * @return id
     */
    @Override
    public String nextId(String key) {
        //log.info("乐观锁序列key:{}",key);
        int updateNum = 0;
        SequenceGeneratorEntity sequenceGeneratorEntity = null;
        do {
            sequenceGeneratorEntity
                    = sequenceGeneratorDao.get(tableName,key);
            if(ObjectUtils.isEmpty(sequenceGeneratorEntity)) {
                log.error("此key:{},查询的序列值为空",key);
                return null;
            }
            updateNum =  sequenceGeneratorDao.update(tableName
                    ,sequenceGeneratorEntity.getSeqKey()
                    ,sequenceGeneratorEntity.getSeqVal()
                    ,sequenceGeneratorEntity.getVersion());
        } while(0 == updateNum);
        long seqVal = sequenceGeneratorEntity.getSeqVal();
        //log.info("乐观锁序列val:{}",seqVal);
        return String.valueOf(seqVal);
    }

}
